package cate.game.role.res.guild.po;

import cate.game.GameBody;
import cate.game.pvp.guildwar.data.GuildWar;
import cate.game.role.Role;
import cate.game.role.res.guild.boss.GuildBossPO;
import cate.game.role.res.guild.msg.GuildDetailResp;
import cate.game.role.res.guild.po.basic.GuildBasicPO;
import cate.game.role.res.guild.po.donate.GuildDonatePO;
import cate.game.role.res.guild.po.envelope.GuildEnvelopePO;
import cate.game.role.res.guild.po.fairyland.GuildFairylandPO;
import cate.game.role.res.guild.po.member.GuildMemberDetailPO;
import cate.game.role.res.guild.po.member.GuildMemberPO;
import cate.game.role.res.guild.po.treasurehouse.GuildTreasureHouse;
import cate.game.util.GameKit;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.function.Consumer;

@NoteClass(value = "guild公会")
@Document(collection = GuildPO.COLLECTION)
public class GuildPO {
    public static final String COLLECTION = "guild.0";

    @NoteField(value = "公会ID")
    @Id
    public String uid;

    @NoteField(value = "公会基本信息")
    public GuildBasicPO basic;

    @NoteField(value = "公会申请")
    public GuildApplyPO apply;

    @NoteField(value = "公会招募")
    public GuildRecruitmentPO recruitment;

    @NoteField(value = "成员管理")
    public GuildMemberPO member;

    @NoteField(value = "公会捐献")
    public GuildDonatePO donate;

    @NoteField(value = "公会活跃度")
    public GuildActivePO active;

    @NoteField(value = "公会红包")
    public GuildEnvelopePO envelope;

    @NoteField(value = "公会boss")
    public GuildBossPO boss;

    @NoteField(value = "公会成员行为记录")
    public GuildRecordPO record;

    @NoteField(value = "公会排名")
    public GuildRankPO rankPO;

    @NoteField(value = "公会宝库")
    public GuildTreasureHouse treasureHouse;

    @NoteField("公会秘境")
    public GuildFairylandPO fairyland;

    @NoteField(value = "公会战")
    public GuildWar war;

    @Transient
    @JsonIgnore
    @NoteField(value = "GameBody")
    public transient GameBody game;


    public GuildPO() {
    }

    public void initialize(GameBody game) {
        this.game = game;
        if (uid == null){
            uid = GameKit.uid();
        }
        if (basic == null) {
            basic = new GuildBasicPO();
        }
        basic.initialize(this);
        if (apply == null) {
            apply = new GuildApplyPO();
        }
        apply.initialize(this);
        if (recruitment == null) {
            recruitment = new GuildRecruitmentPO();
        }
        recruitment.initialize(this);
        if (member == null) {
            member = new GuildMemberPO();
        }
        member.initialize(this);
        if (donate == null) {
            donate = new GuildDonatePO();
        }
        donate.initialize(this);
        if (active == null) {
            active = new GuildActivePO();
        }
        active.initialize(this);
        if (envelope == null) {
            envelope = new GuildEnvelopePO();
        }
        envelope.initialize(this);
        if (boss == null) {
            boss = new GuildBossPO();
        }
        boss.initialize(this);
        if (record == null) {
            record = new GuildRecordPO();
        }
        record.initialize(this);
        if(rankPO == null){
            rankPO = new GuildRankPO();
        }
        rankPO.initialize(this);
        if (treasureHouse == null) {
            treasureHouse = new GuildTreasureHouse();
        }
        treasureHouse.initialize(this);
        if (fairyland == null) {
            fairyland = new GuildFairylandPO();
        }
        fairyland.initialize(this);
        if (war == null) {
            war = new GuildWar();
        }
        war.initialize(this);
    }

    public void onDaySpan() {
        recruitment.onDaySpan();
        donate.onDaySpan();
        active.onDaySpan();
        envelope.onDaySpan();
        member.onDaySpan();
        treasureHouse.onDaySpan();
        war.onDaySpan();
        basic.onDaySpan();
        this.noticeOnline(this::noticeUpdate);
    }

    public void onWeekSpan() {
        active.onWeekSpan();
        treasureHouse.onWeekSpan();
        this.noticeOnline(this::noticeUpdate);
    }

    /**
     * 公会详情变更通知
     */
    @JsonIgnore
    public void noticeUpdate(Role role) {
        role.sendNow(new GuildDetailResp(this));
    }

    /**
     * 更新战力
     */
    public void updatePower() {
        basic.power = member.list.stream().mapToLong(a -> a.it.base.power).sum();
        basic.powerTimeStamp = System.currentTimeMillis();

        GuildMemberDetailPO memberDetail = member.getMember(basic.presidentId);
        if (memberDetail != null) {
            game.crossRank.recordGuildValue(game, memberDetail.it, basic);
        }
    }

    /**
     * 通知在线玩家
     */
    public void noticeOnline(Consumer<Role> action) {
        for (Role role : this.member.getOnlineRole()) {
            action.accept(role);
        }
    }

    public void tick() {
        this.member.tickSelf(this.game);
        this.treasureHouse.tick();
        this.fairyland.tick();
    }
}
